package com.ym.utils.snapPay;

import com.alibaba.fastjson.JSONObject;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.ym.utils.cmDateUtils.DateUtils;
import com.ym.utils.snapPay.sign.SignHandler;
import com.ym.utils.exception.CustomException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.TreeMap;

import static com.ym.utils.snapPay.sign.SignHandler.GSON;

/*@Configuration
@EnableCaching*/
@Component
public class WXAppletApi {

    private static final Logger logger = LoggerFactory.getLogger(WXAppletApi.class);

    private final static String HTTP_URL = "http://3.96.235.52:8080";
    //private final static String HTTP_URL = "https://wechat.icosmetic.ca";
    //private final static String HTTP_URL = "https://tpay.gack.citic";
    private final static String HTTP_URL1 = "https://open.snappay.ca/api/gateway/";
    private final static String Char_Encoding = "UTF-8";
    private final static String Submit_Mode = "POST";
    private final static String Transfer_Mode = "HTTPS";
    private final static String Sign_Type = "MD5";
    private final static String Store_No = "80519419";

    private final static String notify_url = HTTP_URL + "/Order/notify";
    private final static String return_url = HTTP_URL + "/pay/return";

    private final static String Merchant_ID = "902000067173";
    private final static String Signature_Sign_Key = "b1689ffbd1f774ebffdb77f9e80b3537";
    private final static String AppID = "500bfcba97e7a3b0";

    // 微信小程序支付

    public synchronized  Map<String, Object> AppletPay(String orderNo, BigDecimal orderNum, String accountId, String description,
                                                       JSONObject attach, JSONObject exParam) throws CustomException {
        TreeMap<String, Object> map = new TreeMap<>();
        map.put("app_id", AppID);
        System.out.println("支付 回调地址 ：==========="+notify_url);
        map.put("notify_url", notify_url); // 	后台通知地址 商家后台接收开放服务网关支付异步通知回调地址 256
        map.put("merchant_no", Merchant_ID); // 商户号，在SnapPay入驻后生成的定常数字，用于标识商户身份  32
        map.put("format", "JSON");
        map.put("charset", "UTF-8");
        map.put("version", "1.0");
        map.put("timestamp", DateUtils.getUTCTime());
        map.put("method", "pay.minipay"); // 请求方法  此接口固定值为：pay.minipay   128
        map.put("payment_method", "WECHATPAY"); // 支付方式  目前只支付：WECHATPAY-微信支付 16
        map.put("trans_currency", "CAD"); //	符合ISO 4217标准的三位字母代码，如：CAD，USD标价币种必须与商户申请的结算币种一致，不填写则默认为CAD 8
        map.put("effective_minutes", 10); // 设置订单有效分钟数，超出有效时长不支付，订单将被关闭，不能再进行支付，默认为5分钟 取值范围：5分钟—60分钟

        map.put("out_order_no", orderNo); // 商户系统内部订单号，可以视为交易流水号，同一商户下订单号不能重复，即使交易没有成功 64
        //商户在微信公众平台申请移动应用或小程序得到的APPID（此APPID需要发邮件给SnapPay进行绑定）。
        // 当您在SnapPay绑定了多个APPID时，此为必选项，指定当前交易请求所使用的APPID
        map.put("sub_app_id", AppID);//微信公众平台分配的App Id
        map.put("trans_amount", orderNum); //最大值：100000000.00
        map.put("pay_user_account_id", accountId); // 用户子标识 微信Openid，下单前需要调用【网页授权获取用户信息】接口获取到用户的Openid。 64
        map.put("description", description); //	订单描述 支付订单的简要描述。例：Ipad mini 16G 白色  128

        map.put("attach", attach); //商户附加信息 附加数据。该字段主要用于商户携带订单的自定义数据，且需要遵循JSON格式。在查询API和支付通知中原样返回 127
        map.put("extension_parameters", exParam); // 扩展参数 扩展输入参数，后续定义增加的参数存储于此JSON可变结构中

        JsonObject paramsJson = GSON.toJsonTree(map).getAsJsonObject();
        String sign = SignHandler.signWithMD5(paramsJson, Signature_Sign_Key);
        System.out.println("sign-签名：" + sign);
        map.put("sign", sign);
        map.put("sign_type", Sign_Type);

        Gson gson = new Gson();
        String gsonJSON = gson.toJson(map);
        System.out.println("入参json " + gsonJSON);

        Map<String, Object> resultMap = null;
        try {
            String mapJson = HttpPostUtils.doPost(HTTP_URL1, gsonJSON);
            resultMap = gson.fromJson(mapJson, Map.class);
            System.out.println("msg : " + resultMap.get("msg"));
            System.out.println("sign : " + resultMap.get("sign"));
            if (resultMap.get("code").equals("0") == true && resultMap.get("msg").equals("success") == true) {
                JsonObject resultJson = JsonParser.parseString(mapJson).getAsJsonObject();
                boolean isPass = SignHandler.verifySign(resultJson, Signature_Sign_Key);
                if (isPass == true) {
                    //业务
                    if(resultMap.get("msg").equals("success")==false){
                        throw new CustomException(500, "业务失败!");
                    }
                  /*  for (Map.Entry<String, Object> entry : resultMap.entrySet()) {
                        System.out.println(entry.getKey() + ": " + entry.getValue());
                    }*/
                } else {
                    logger.error("签名验证失败!");
                    throw new CustomException(500, "签名验证失败!");
                }
            }
        } catch (Exception e) {
            logger.error("调用异常!"+e.getMessage());
            throw new CustomException(500, e.getMessage());
        }
        return resultMap;
    }

    /*public static void main(String[] args) {
        System.out.println("开始时间: "+System.currentTimeMillis()+"::"+ DateUtils.getDateForStr(new Date()));
        try{
            AppletPay("20200329223015901212214",new BigDecimal("0.01"),"oiA_t4hrw6EBZly3qJyZPCvu4CxU","Ipad mini 16G 白色  128",null,null);
        }catch (Exception e){
            System.out.println(e.getMessage());
        }
        System.out.println("结束时间: "+System.currentTimeMillis()+"::"+ DateUtils.getDateForStr(new Date()));
    }*/
    /**
     * sign-签名：afdac08d26aa0e261d02c73ac3439100
     * 入参json {"app_id":"500bfcba97e7a3b0","attach":{"infor":"纯白色的ipad"},"charset":"UTF-8","description":"Ipad mini 16G 白色","effective_minutes":15,"extension_parameters":{"kz":"kz纯白色的ipad"},"format":"JSON","merchant_no":"902000067173","method":"pay.minipay","notify_url":"http://chenxi.gz2vip.idcfengye.com/Order/notify","out_order_no":"121xcqq1v","pay_user_account_id":"oSATF5IA137VIAmXd92RDylKc3k8","payment_method":"WECHATPAY","sign":"afdac08d26aa0e261d02c73ac3439100","sign_type":"MD5","sub_app_id":"500bfcba97e7a3b0","timestamp":"2020-07-17 14:28:23","trans_amount":0.01,"trans_currency":"CAD","version":"1.0"}
     * msg : success
     * sign : 161781ca4ae09ab970fc32e85b6b6d33
     * code: 0
     * data: [{trans_no=TW120000671200717000001, merchant_no=902000067173, request_payment={timeStamp=1594996111, package=prepay_id=wx17222831839186958e6920a71430983300, paySign=AA19AE9D6D2D58ABF43FFEA1026796FC, appId=wx7e4032077c7178f3, signType=MD5, nonceStr=0aejNMEctr6Z0Iig}, out_order_no=121xcqq1v, trans_status=USERPAYING}]
     * msg: success
     * psn: 07171428303821462250
     * sign: 161781ca4ae09ab970fc32e85b6b6d33
     * total: 1.0
     */
    //微信小程序支付
   /* public static void main(String[] args) throws CustomException {
        System.out.println("执行调度方法");
        JSONObject json = new JSONObject();
        json.put("infor", "纯白色的ipad");
        JSONObject json1 = new JSONObject();
        json1.put("kz", "kz纯白色的ipad");
        AppletPay("121xcqq1v",new BigDecimal("0.01"),"oSATF5IA137VIAmXd92RDylKc3k8","Ipad mini 16G 白色",json,json1);
    }*/


    // WEB网页支付
    public synchronized Map<String, Object> webPay(String paymentMethod, String browser_type, String orderNo, BigDecimal orderNum, String subject, String description,
                                                   JSONObject attach, JSONObject exParam) throws CustomException {
        TreeMap<String, Object> map = new TreeMap<>();
        map.put("app_id", AppID);
        map.put("notify_url", notify_url); // 	后台通知地址 商家后台接收开放服务网关支付异步通知回调地址 256
        map.put("refer_url", return_url);
        map.put("merchant_no", Merchant_ID); // 商户号，在SnapPay入驻后生成的定常数字，用于标识商户身份  32
        map.put("format", "JSON");
        map.put("charset", "UTF-8");
        map.put("version", "1.0");
        //map.put("timestamp", DateUtils.getUTCTime());
        map.put("method", "pay.webpay"); // 请求方法  此接口固定值为：pay.webPay   128
        map.put("payment_method", paymentMethod); // 支付方式  目前支持的支付方式有：ALIPAY-支付宝 WECHATPAY-微信支付
        map.put("trans_currency", "CAD"); //	符合ISO 4217标准的三位字母代码，如：CAD，USD标价币种必须与商户申请的结算币种一致，不填写则默认为CAD 8
        map.put("effective_minutes", 15); // 设置订单有效分钟数，超出有效时长不支付，订单将被关闭，不能再进行支付，默认为5分钟 取值范围：5分钟—60分钟

        map.put("out_order_no", orderNo); // 商户系统内部订单号，可以视为交易流水号，同一商户下订单号不能重复，即使交易没有成功 64
        //商户在微信公众平台申请移动应用或小程序得到的APPID（此APPID需要发邮件给SnapPay进行绑定）。
        // 当您在SnapPay绑定了多个APPID时，此为必选项，指定当前交易请求所使用的APPID
        map.put("browser_type", browser_type);//PC：电脑网站支付，默认  WAP：手机网站支付  UNIONPAY仅支付PC网站支付
        map.put("trans_amount", orderNum); //最大值：100000000.00
        map.put("subject", subject); // 商品的名称。例：Ipad 128
        map.put("description", description); //	订单描述 支付订单的简要描述。例：Ipad mini 16G 白色  128

        map.put("attach", attach); //商户附加信息 附加数据。该字段主要用于商户携带订单的自定义数据，且需要遵循JSON格式。在查询API和支付通知中原样返回 127
        map.put("extension_parameters", exParam); // 扩展参数 扩展输入参数，后续定义增加的参数存储于此JSON可变结构中

        JsonObject paramsJson = GSON.toJsonTree(map).getAsJsonObject();
        String sign = SignHandler.signWithMD5(paramsJson, Signature_Sign_Key);
        System.out.println("sign-签名：" + sign);
        map.put("sign", sign);
        map.put("sign_type", Sign_Type);

        Gson gson = new Gson();
        String gsonJSON = gson.toJson(map);
        System.out.println("入参json " + gsonJSON);

        Map<String, Object> resultMap = null;
        try {
            String mapJson = HttpPostUtils.doPost(HTTP_URL1, gsonJSON);
            resultMap = gson.fromJson(mapJson, Map.class);
            System.out.println("msg : " + resultMap.get("msg"));
            System.out.println("sign : " + resultMap.get("sign"));
            if (resultMap.get("code").equals("0") == true && resultMap.get("msg").equals("success") == true) {
                JsonObject resultJson = JsonParser.parseString(mapJson).getAsJsonObject();
                boolean isPass = SignHandler.verifySign(resultJson, Signature_Sign_Key);
                if (isPass == true) {
                    //业务
                    for (Map.Entry<String, Object> entry : resultMap.entrySet()) {
                        System.out.println(entry.getKey() + ": " + entry.getValue());
                    }
                } else {
                    logger.error("签名验证失败!");
                    throw new CustomException(500, "签名验证失败!");
                }
            }
        } catch (Exception e) {
            logger.error("调用异常!");
            e.printStackTrace();
            throw new CustomException(500, "调用异常!");
        }
        return null;
    }
    // WEB网页支付
    /*  public static void main(String[] args) {
        System.out.println("执行调度方法");
        JSONObject json = new JSONObject();
        json.put("infor", "纯白色的ipad");
        JSONObject json1 = new JSONObject();
        json1.put("kz", "kz纯白色的ipad");
        webPay("ALIPAY",AppID,"web012341",new BigDecimal("0.01"),"ipad","Ipad mini 16G 白色",json,json1);
       // System.out.println(DateUtils.getUTCTime());

    }*/

    // 扫码支付
    public synchronized static Map<String, Object> scodePay(String paymentMethod, String store_no, String orderNo, BigDecimal orderNum, String subject, String description,
                                                            JSONObject attach, JSONObject exParam) throws CustomException {
        TreeMap<String, Object> map = new TreeMap<>();
        map.put("app_id", AppID);
        map.put("notify_url", notify_url); // 	后台通知地址 商家后台接收开放服务网关支付异步通知回调地址 256
        map.put("merchant_no", Merchant_ID); // 商户号，在SnapPay入驻后生成的定常数字，用于标识商户身份  32
        map.put("format", "JSON");
        map.put("charset", "UTF-8");
        map.put("version", "1.0");
        //map.put("timestamp", DateUtils.getUTCTime());
        map.put("method", "pay.qrcodepay"); // 请求方法  此接口固定值为：pay.minipay   128
        map.put("payment_method", paymentMethod); // ALIPAY-支付宝 WECHATPAY-微信支付 UNIONPAY_QR-银联云闪付
        map.put("trans_currency", "CAD"); //	符合ISO 4217标准的三位字母代码，如：CAD，USD标价币种必须与商户申请的结算币种一致，不填写则默认为CAD 8
        map.put("effective_minutes", 15); // 设置订单有效分钟数，超出有效时长不支付，订单将被关闭，不能再进行支付，默认为5分钟 取值范围：5分钟—60分钟

        map.put("out_order_no", orderNo); // 商户系统内部订单号，可以视为交易流水号，同一商户下订单号不能重复，即使交易没有成功 64
        //商户在微信公众平台申请移动应用或小程序得到的APPID（此APPID需要发邮件给SnapPay进行绑定）。
        // 当您在SnapPay绑定了多个APPID时，此为必选项，指定当前交易请求所使用的APPID
        map.put("store_no", store_no);//SnapPay分配的门店号 门店号用于区分同一个商户的不同门店。该号码由SnapPay在创建商户时分配。我们建议在请求中提供门店号以便于通过支付宝的风险控制。例如：“store_no”:“80000026”
        map.put("trans_amount", orderNum); //最大值：100000000.00
        map.put("subject", subject); // 商品的名称。例：Ipad 128
        map.put("description", description); //	订单描述 支付订单的简要描述。例：Ipad mini 16G 白色  128

        map.put("attach", attach); //商户附加信息 附加数据。该字段主要用于商户携带订单的自定义数据，且需要遵循JSON格式。在查询API和支付通知中原样返回 127
        map.put("extension_parameters", exParam); // 扩展参数 扩展输入参数，后续定义增加的参数存储于此JSON可变结构中

        JsonObject paramsJson = GSON.toJsonTree(map).getAsJsonObject();
        String sign = SignHandler.signWithMD5(paramsJson, Signature_Sign_Key);
        System.out.println("sign-签名：" + sign);
        map.put("sign", sign);
        map.put("sign_type", Sign_Type);

        Gson gson = new Gson();
        String gsonJSON = gson.toJson(map);
        System.out.println("入参json " + gsonJSON);

        Map<String, Object> resultMap = null;
        try {
            String mapJson = HttpPostUtils.doPost(HTTP_URL1, gsonJSON);
            resultMap = gson.fromJson(mapJson, Map.class);
            System.out.println("msg : " + resultMap.get("msg"));
            System.out.println("sign : " + resultMap.get("sign"));
            if (resultMap.get("code").equals("0") == true && resultMap.get("msg").equals("success") == true) {
                JsonObject resultJson = JsonParser.parseString(mapJson).getAsJsonObject();
                boolean isPass = SignHandler.verifySign(resultJson, Signature_Sign_Key);
                if (isPass == true) {
                    //业务
                    for (Map.Entry<String, Object> entry : resultMap.entrySet()) {
                        System.out.println(entry.getKey() + ": " + entry.getValue());
                    }
                } else {
                    logger.error("签名验证失败!");
                    throw new CustomException(500, "签名验证失败!");
                }
            }
        } catch (Exception e) {
            logger.error("调用异常 !");
            e.printStackTrace();
            throw new CustomException(500, "调用异常!");
        }
        return null;
    }

    //扫码
  /*  public static void main(String[] args) throws CustomException {
        System.out.println("执行调度方法");
        JSONObject json = new JSONObject();
        json.put("infor", "纯白色的ipad");
        JSONObject json1 = new JSONObject();
        json1.put("kz", "kz纯白色的ipad");
        scodePay("WECHATPAY", null, "cs1036", new BigDecimal("0.01"), "ipad", "Ipad mini 16G 白色", json, json1);
    }*/


    //H5 支付
    public synchronized Map<String, Object> H5Pay(String paymentMethod, String userAccountId, String orderNo, BigDecimal orderNum, String description,
                                                  JSONObject attach, JSONObject exParam) throws CustomException {
        TreeMap<String, Object> map = new TreeMap<>();
        map.put("app_id", AppID);
        map.put("notify_url", notify_url); // 	后台通知地址 商家后台接收开放服务网关支付异步通知回调地址 256
        map.put("return_url", return_url);
        map.put("merchant_no", Merchant_ID); // 商户号，在SnapPay入驻后生成的定常数字，用于标识商户身份  32
        map.put("format", "JSON");
        map.put("charset", "UTF-8");
        map.put("version", "1.0");
        //map.put("timestamp", DateUtils.getUTCTime());
        map.put("method", "pay.h5pay"); // 请求方法  此接口固定值为：pay.minipay   128
        map.put("payment_method", paymentMethod); // 目前支持的支付方式有：ALIPAY-支付宝  WECHATPAY-微信支付
        if (paymentMethod.equals("ALIPAY")) {
            map.put("pay_channel_trade_type", "JSAPI");
            map.put("pay_user_account_id", userAccountId);
        }
        map.put("trans_currency", "CAD"); //	符合ISO 4217标准的三位字母代码，如：CAD，USD标价币种必须与商户申请的结算币种一致，不填写则默认为CAD 8
        map.put("effective_minutes", 15); // 设置订单有效分钟数，超出有效时长不支付，订单将被关闭，不能再进行支付，默认为5分钟 取值范围：5分钟—60分钟

        map.put("out_order_no", orderNo); // 商户系统内部订单号，可以视为交易流水号，同一商户下订单号不能重复，即使交易没有成功 64
        //商户在微信公众平台申请移动应用或小程序得到的APPID（此APPID需要发邮件给SnapPay进行绑定）。
        // 当您在SnapPay绑定了多个APPID时，此为必选项，指定当前交易请求所使用的APPID
        map.put("trans_amount", orderNum); //最大值：100000000.00
        map.put("description", description); //	订单描述 支付订单的简要描述。例：Ipad mini 16G 白色  128
        map.put("attach", attach); //商户附加信息 附加数据。该字段主要用于商户携带订单的自定义数据，且需要遵循JSON格式。在查询API和支付通知中原样返回 127
        map.put("extension_parameters", exParam); // 扩展参数 扩展输入参数，后续定义增加的参数存储于此JSON可变结构中
        JsonObject paramsJson = GSON.toJsonTree(map).getAsJsonObject();
        String sign = SignHandler.signWithMD5(paramsJson, Signature_Sign_Key);
        System.out.println("sign-签名：" + sign);
        map.put("sign", sign);
        map.put("sign_type", Sign_Type);

        Gson gson = new Gson();
        String gsonJSON = gson.toJson(map);
        System.out.println("入参json " + gsonJSON);

        Map<String, Object> resultMap = null;
        try {
            String mapJson = HttpPostUtils.doPost(HTTP_URL1, gsonJSON);
            resultMap = gson.fromJson(mapJson, Map.class);
            System.out.println("msg : " + resultMap.get("msg"));
            System.out.println("sign : " + resultMap.get("sign"));
            if (resultMap.get("code").equals("0") == true && resultMap.get("msg").equals("success") == true) {
                JsonObject resultJson = JsonParser.parseString(mapJson).getAsJsonObject();
                boolean isPass = SignHandler.verifySign(resultJson, Signature_Sign_Key);
                if (isPass == true) {
                    //业务
                    for (Map.Entry<String, Object> entry : resultMap.entrySet()) {
                        System.out.println(entry.getKey() + ": " + entry.getValue());
                    }
                } else {
                    logger.error("签名验证失败!");
                    throw new CustomException(500, "签名验证失败!");
                }
            }
        } catch (Exception e) {
            logger.error("调用异常 !");
            e.printStackTrace();
            throw new CustomException(500, "调用异常!");
        }
        return null;
    }

  /*  public static void main(String[] args) {
        System.out.println("执行调度方法");
        JSONObject json = new JSONObject();
        json.put("infor", "纯白色的ipad");
        JSONObject json1 = new JSONObject();
        json1.put("kz", "kz纯白色的ipad");
        H5Pay("WECHATPAY", null,"h5002", new BigDecimal("0.01"), "Ipad mini 16G 白色", json, json1);
    }*/


    //订单查询
    public Map<String, Object> queryOrder(String orderNo, String trans_no, JSONObject exParam) throws CustomException {
        TreeMap<String, Object> map = new TreeMap<>();
        map.put("app_id", AppID);
        //map.put("notify_url", notify_url); // 	后台通知地址 商家后台接收开放服务网关支付异步通知回调地址 256
        map.put("merchant_no", Merchant_ID); // 商户号，在SnapPay入驻后生成的定常数字，用于标识商户身份  32
        map.put("format", "JSON");
        map.put("charset", "UTF-8");
        map.put("version", "1.0");
        map.put("timestamp", DateUtils.getUTCTime());
        map.put("method", "pay.orderquery"); // 请求方法  此接口固定值为：pay.minipay   128

        //map.put("trans_no", trans_no); //开放服务网关平台交易号。out_order_no或trans_no两个参数需提供一个
        map.put("out_order_no", orderNo); // 商户系统内部订单号，同一商户下订单号不能重复。out_order_no或trans_no两个参数需提供一个

        map.put("extension_parameters", exParam); // 扩展参数 扩展输入参数，后续定义增加的参数存储于此JSON可变结构中
        JsonObject paramsJson = GSON.toJsonTree(map).getAsJsonObject();
        String sign = SignHandler.signWithMD5(paramsJson, Signature_Sign_Key);
        System.out.println("sign-签名：" + sign);
        map.put("sign", sign);
        map.put("sign_type", Sign_Type);

        Gson gson = new Gson();
        String gsonJSON = gson.toJson(map);
        System.out.println("入参json " + gsonJSON);

        Map<String, Object> resultMap = null;
        try {
            String mapJson = HttpPostUtils.doPost(HTTP_URL1, gsonJSON);
            resultMap = gson.fromJson(mapJson, Map.class);
            System.out.println("msg : " + resultMap.get("msg"));
            System.out.println("sign : " + resultMap.get("sign"));
            if (resultMap.get("code").equals("0") == true && resultMap.get("msg").equals("success") == true) {
                JsonObject resultJson = JsonParser.parseString(mapJson).getAsJsonObject();
                boolean isPass = SignHandler.verifySign(resultJson, Signature_Sign_Key);
                if (isPass == true) {
                    //业务
                    for (Map.Entry<String, Object> entry : resultMap.entrySet()) {
                        System.out.println(entry.getKey() + ": " + entry.getValue());
                    }
                } else {
                    logger.error("签名验证失败!");
                    throw new CustomException(500, "签名验证失败!");
                }
            }
        } catch (Exception e) {
            logger.error("调用异常 !");
            e.printStackTrace();
            throw new CustomException(500, "调用异常!");
        }
        return null;
    }
    //订单查询
/*    public static void main(String[] args) {
        System.out.println("执行调度方法");
        JSONObject json = new JSONObject();
        json.put("infor", "纯白色的ipad");
        JSONObject json1 = new JSONObject();
        json1.put("kz", "kz纯白色的ipad");
        queryOrder("sc101",null,json1);
    }*/

    //回调
    public synchronized static Map<String, Object> notify(HttpServletRequest request, HttpServletResponse response) throws CustomException {
        Map<String, Object> resultMap = null;
        try {
            Gson gson = new Gson();
            InputStream inputStream = request.getInputStream();
            ByteArrayOutputStream result = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int length;
            while ((length = inputStream.read(buffer)) != -1) {
                result.write(buffer, 0, length);
            }
            String mapJson = result.toString(StandardCharsets.UTF_8.name());
            resultMap = gson.fromJson(mapJson, Map.class);
            JsonObject resultJson = JsonParser.parseString(mapJson).getAsJsonObject();
            boolean isPass = SignHandler.verifySign(resultJson, Signature_Sign_Key);
            if (isPass == true) {
                return resultMap;
                //业务
              /*  for (Map.Entry<String, Object> entry : resultMap.entrySet()) {
                    System.out.println(entry.getKey() + ": " + entry.getValue());
                }*/
               /* Map map =new HashMap();
                map.put("code", "0");*/
              /*  response.setContentType("application/json;charset=UTF-8");
                PrintWriter printWriter = response.getWriter();
                printWriter.write(JSON.toJSONString(map));
                printWriter.flush();
                printWriter.close();
                return null;*/
            } else {
                logger.error("签名验证失败!");
                throw new CustomException(500, "签名验证失败!");
            }

        } catch (Exception e) {
            logger.error("调用异常 !");
            e.printStackTrace();
            throw new CustomException(500, "调用异常!");
        }
    }


    //订单撤销
    public Map<String, Object> orderCancel(String orderNo, JSONObject exParam) throws CustomException {
        TreeMap<String, Object> map = new TreeMap<>();
        map.put("app_id", AppID);
        //map.put("notify_url", notify_url); // 	后台通知地址 商家后台接收开放服务网关支付异步通知回调地址 256
        map.put("merchant_no", Merchant_ID); // 商户号，在SnapPay入驻后生成的定常数字，用于标识商户身份  32
        map.put("format", "JSON");
        map.put("charset", "UTF-8");
        map.put("version", "1.0");
        map.put("timestamp", DateUtils.getUTCTime());
        map.put("method", "pay.ordercancel"); // 请求方法  此接口固定值为：pay.minipay   128
        map.put("out_order_no", orderNo); // 商户系统内部订单号，同一商户下订单号不能重复。out_order_no或trans_no两个参数需提供一个
        map.put("extension_parameters", exParam); // 扩展参数 扩展输入参数，后续定义增加的参数存储于此JSON可变结构中

        JsonObject paramsJson = GSON.toJsonTree(map).getAsJsonObject();
        String sign = SignHandler.signWithMD5(paramsJson, Signature_Sign_Key);
        System.out.println("sign-签名：" + sign);
        map.put("sign", sign);
        map.put("sign_type", Sign_Type);

        Gson gson = new Gson();
        String gsonJSON = gson.toJson(map);
        System.out.println("入参json " + gsonJSON);

        Map<String, Object> resultMap = null;
        try {
            String mapJson = HttpPostUtils.doPost(HTTP_URL1, gsonJSON);
            resultMap = gson.fromJson(mapJson, Map.class);
            System.out.println("msg : " + resultMap.get("msg"));
            System.out.println("sign : " + resultMap.get("sign"));
            if (resultMap.get("code").equals("0") == true && resultMap.get("msg").equals("success") == true) {
                JsonObject resultJson = JsonParser.parseString(mapJson).getAsJsonObject();
                boolean isPass = SignHandler.verifySign(resultJson, Signature_Sign_Key);
                if (isPass == true) {
                    //业务
                   /* for (Map.Entry<String, Object> entry : resultMap.entrySet()) {
                        System.out.println(entry.getKey() + ": " + entry.getValue());
                    }*/
                } else {
                    logger.error("签名验证失败!");
                    throw new CustomException(500, "签名验证失败!");
                }
            }
        } catch (Exception e) {
            logger.error("调用异常 !");
            e.printStackTrace();
            throw new CustomException(500, "调用异常!");
        }
        return resultMap;
    }
    //订单撤销
   /* public static void main(String[] args) {
        System.out.println("执行调度方法");
        JSONObject json = new JSONObject();
        json.put("infor", "纯白色的ipad");
        orderCancel("sc104",json);
    }*/


    //订单退款
    public synchronized Map<String, Object> orderRefund(String orderNo, String out_refund_no,
                                                        BigDecimal refund_amount, String refund_desc, JSONObject exParam) throws CustomException {
        TreeMap<String, Object> map = new TreeMap<>();
        map.put("app_id", AppID);
        map.put("merchant_no", Merchant_ID); // 商户号，在SnapPay入驻后生成的定常数字，用于标识商户身份  32
        map.put("format", "JSON");
        map.put("charset", "UTF-8");
        map.put("version", "1.0");
        map.put("timestamp", DateUtils.getUTCTime());
        map.put("method", "pay.orderrefund"); // 请求方法  此接口固定值为：pay.minipay   128
        map.put("out_order_no", orderNo); // 商户系统内部订单号，同一商户下订单号不能重复。out_order_no或trans_no两个参数需提供一个
        map.put("out_refund_no", out_refund_no);//商户系统内部的退款单号，商户系统内部唯一，同一退款单号多次请求只退一笔。当前退款交易的订单号
        map.put("refund_amount", refund_amount); //本次申请退款金额
        map.put("refund_desc", refund_desc); //本次申请退款金额
        map.put("extension_parameters", exParam); // 扩展参数 扩展输入参数，后续定义增加的参数存储于此JSON可变结构中

        JsonObject paramsJson = GSON.toJsonTree(map).getAsJsonObject();
        String sign = SignHandler.signWithMD5(paramsJson, Signature_Sign_Key);
        System.out.println("sign-签名：" + sign);
        map.put("sign", sign);
        map.put("sign_type", Sign_Type);

        Gson gson = new Gson();
        String gsonJSON = gson.toJson(map);
        System.out.println("入参json " + gsonJSON);

        Map<String, Object> resultMap = null;
        try {
            String mapJson = HttpPostUtils.doPost(HTTP_URL1, gsonJSON);
            resultMap = gson.fromJson(mapJson, Map.class);
            System.out.println("msg : " + resultMap.get("msg"));
            System.out.println("sign : " + resultMap.get("sign"));
            if (resultMap.get("code").equals("0") == true && resultMap.get("msg").equals("success") == true) {
                JsonObject resultJson = JsonParser.parseString(mapJson).getAsJsonObject();
                boolean isPass = SignHandler.verifySign(resultJson, Signature_Sign_Key);
                if (isPass == true) {
                    //业务
                    for (Map.Entry<String, Object> entry : resultMap.entrySet()) {
                        System.out.println(entry.getKey() + ": " + entry.getValue());
                    }
                } else {
                    logger.error("签名验证失败!");
                    throw new CustomException(500, "签名验证失败!");
                }
            }
        } catch (Exception e) {
            logger.error("调用异常 !");
            e.printStackTrace();
            throw new CustomException(500, "调用异常!");
        }
        return resultMap;
    }

   /* public static void main(String[] args) {
        System.out.println("执行调度方法");
        JSONObject json = new JSONObject();
        json.put("infor", "纯白色的ipad");
        orderRefund("sc101", "rf001", new BigDecimal("0.01"), "测试退款", json);
    }*/
  /* public static void main(String[] args) {
       BigDecimal discountPrice=new BigDecimal("0");
            BigDecimal a= new BigDecimal("102");
            BigDecimal b= new BigDecimal("103");
       discountPrice=a.add(b);
       System.out.println(discountPrice);
   }*/
}
